﻿using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace VisionDetectionWifi.halconAlgorithm
{
    internal class HDevelopExport_6
    {
        public HTuple hv_ExpDefaultWinHandle;

        // Main procedure
        private void action()
        {
            // Stack for temporary objects
            HObject[] OTemp = new HObject[20];

            // Local iconic variables

            HTuple width = null, height = null;
            HObject ho_Image, ho_GrayImage, ho_Region;
            HObject ho_ConnectedRegions, ho_SelectedRegions, ho_RegionTrans;
            HObject ho_RegionFillUp, ho_RegionUnion, ho_ImageReduced1;
            HObject ho_SortedRegions, ho_EmptyObject, ho_ObjectSelected = null;
            HObject ho_ImageReduced2 = null, ho_SymbolXLDs = null;

            // Local control variables

            HTuple hv_WindowHandle = new HTuple(), hv_Area1 = null;
            HTuple hv_Row4 = null, hv_Column4 = null, hv_Phi = null;
            HTuple hv_angle = null, hv_Number = null, hv_QRCode_information = null;
            HTuple hv_i = null, hv_DataCodeHandle = new HTuple(), hv_ResultHandles = new HTuple();
            HTuple hv_DecodedDataStrings = new HTuple();
            // Initialize local and output iconic variables
            HOperatorSet.GenEmptyObj(out ho_Image);
            HOperatorSet.GenEmptyObj(out ho_GrayImage);
            HOperatorSet.GenEmptyObj(out ho_Region);
            HOperatorSet.GenEmptyObj(out ho_ConnectedRegions);
            HOperatorSet.GenEmptyObj(out ho_SelectedRegions);
            HOperatorSet.GenEmptyObj(out ho_RegionTrans);
            HOperatorSet.GenEmptyObj(out ho_RegionFillUp);
            HOperatorSet.GenEmptyObj(out ho_RegionUnion);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced1);
            HOperatorSet.GenEmptyObj(out ho_SortedRegions);
            HOperatorSet.GenEmptyObj(out ho_EmptyObject);
            HOperatorSet.GenEmptyObj(out ho_ObjectSelected);
            HOperatorSet.GenEmptyObj(out ho_ImageReduced2);
            HOperatorSet.GenEmptyObj(out ho_SymbolXLDs);
            //*一、为了提高二维码区域查找的准确性，必须利用Blob分析将查找的区域缩小
            //*由于图片是彩色的，不利于进行阈值分割，需要将RGB图像转化成灰度值图像
            //dev_close_window(...);
            //dev_open_window(...);
            ho_Image.Dispose();
            HOperatorSet.ReadImage(out ho_Image, "wifi样品3.png");

            HOperatorSet.GetImageSize(ho_Image, out width, out height);

            //get_image_size (Image, Width, Height)
            ho_GrayImage.Dispose();
            HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);

            //draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
            //gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
            //reduce_domain (GrayImage, Rectangle, ImageReduced)
            //将ImageReduced内阈值在130到255之间的区域筛选出来
            ho_Region.Dispose();
            HOperatorSet.Threshold(ho_GrayImage, out ho_Region, 175, 255);
            //将Region区域分离成一个个独立的区域
            ho_ConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_Region, out ho_ConnectedRegions);
            //将ConnectedRegions区域内面O积在9000到99999之间的区域筛选出来
            ho_SelectedRegions.Dispose();
            HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area",
                "and", 19000, 999999);
            //将SelectedRegions区域的形状转化成带倾斜角度的矩形区域
            ho_RegionTrans.Dispose();
            HOperatorSet.ShapeTrans(ho_SelectedRegions, out ho_RegionTrans, "rectangle2");
            //填充RegionTrans区域
            ho_RegionFillUp.Dispose();
            HOperatorSet.FillUp(ho_RegionTrans, out ho_RegionFillUp);

            //将RegionFillUp区域扩大30个像素点
            //dilation_rectangle1 (RegionFillUp, RegionDilation, 30, 30)
            //查找RegionDilation区域内每个区域的面积和中心点坐标
            HOperatorSet.AreaCenter(ho_RegionFillUp, out hv_Area1, out hv_Row4, out hv_Column4);

            //计算每个区域的角度
            HOperatorSet.OrientationRegion(ho_RegionFillUp, out hv_Phi);
            hv_angle = hv_Phi.TupleDeg();

            //利用查找出来的中心点坐标画矩形
            //gen_rectangle1 (Rectangle1, Row4 - 555, Column4 - 371, Row4 + 555, Column4 + 371)

            //**二、剔除了不必要区域的干扰后，就可以在理想的区域内进行二维码查找和内容解析
            //将Rectangle1区域结合成一个区域
            ho_RegionUnion.Dispose();
            HOperatorSet.Union1(ho_RegionFillUp, out ho_RegionUnion);
            ho_ImageReduced1.Dispose();
            HOperatorSet.ReduceDomain(ho_GrayImage, ho_RegionUnion, out ho_ImageReduced1);
            ho_ConnectedRegions.Dispose();
            HOperatorSet.Connection(ho_ImageReduced1, out ho_ConnectedRegions);
            //计算出ConnectedRegions内区域的个数
            HOperatorSet.CountObj(ho_ConnectedRegions, out hv_Number);
            //将ConnectedRegions内的区域按照行排序，并且用数字代表相应的区域
            ho_SortedRegions.Dispose();
            HOperatorSet.SortRegion(ho_ConnectedRegions, out ho_SortedRegions, "first_point",
                "true", "column");
            //建立一个空的项目
            ho_EmptyObject.Dispose();
            HOperatorSet.GenEmptyObj(out ho_EmptyObject);
            hv_QRCode_information = 0;
            HTuple end_val46 = hv_Number;
            HTuple step_val46 = 1;
            for (hv_i = 1; hv_i.Continue(end_val46, step_val46); hv_i = hv_i.TupleAdd(step_val46))
            {
                //根据i的数值选择SortedRegions内排序的区域
                ho_ObjectSelected.Dispose();
                HOperatorSet.SelectObj(ho_SortedRegions, out ho_ObjectSelected, hv_i);
                ho_ImageReduced2.Dispose();
                HOperatorSet.ReduceDomain(ho_GrayImage, ho_ObjectSelected, out ho_ImageReduced2
                    );
                //建立QR Code类型的二维码模型句柄
                HOperatorSet.CreateDataCode2dModel("QR Code", new HTuple(), new HTuple(), out hv_DataCodeHandle);
                //在ImageReduced2内查找二维码轮廓和解析其内容
                ho_SymbolXLDs.Dispose();
                HOperatorSet.FindDataCode2d(ho_ImageReduced2, out ho_SymbolXLDs, hv_DataCodeHandle,
                    "train", "all", out hv_ResultHandles, out hv_DecodedDataStrings);
                if (hv_QRCode_information == null)
                    hv_QRCode_information = new HTuple();
                hv_QRCode_information[hv_i - 1] = hv_DecodedDataStrings;
                {
                    HObject ExpTmpOutVar_0;
                    HOperatorSet.ConcatObj(ho_SymbolXLDs, ho_EmptyObject, out ExpTmpOutVar_0);
                    ho_EmptyObject.Dispose();
                    ho_EmptyObject = ExpTmpOutVar_0;
                }
            }
            HOperatorSet.SetColor(hv_ExpDefaultWinHandle, "green");

            //设置缩放
            HOperatorSet.SetPart(hv_ExpDefaultWinHandle, 0, 0, height, width);

            //显示区域
            HOperatorSet.DispObj(ho_GrayImage, hv_ExpDefaultWinHandle);
            HOperatorSet.DispObj(ho_EmptyObject, hv_ExpDefaultWinHandle);

            //显示二维码信息
            HOperatorSet.SetTposition(hv_ExpDefaultWinHandle, (hv_Row4.TupleSelect(2)) - 50,
                (hv_Column4.TupleSelect(2)) - 10);
            HOperatorSet.WriteString(hv_ExpDefaultWinHandle, "二维码信息：" + (hv_QRCode_information.TupleSelect(
                0)));
            HOperatorSet.SetTposition(hv_ExpDefaultWinHandle, (hv_Row4.TupleSelect(1)) - 50,
                (hv_Column4.TupleSelect(1)) - 10);
            HOperatorSet.WriteString(hv_ExpDefaultWinHandle, "二维码信息：" + (hv_QRCode_information.TupleSelect(
                1)));
            HOperatorSet.SetTposition(hv_ExpDefaultWinHandle, (hv_Row4.TupleSelect(0)) - 50,
                (hv_Column4.TupleSelect(0)) - 10);
            HOperatorSet.WriteString(hv_ExpDefaultWinHandle, "二维码信息：" + (hv_QRCode_information.TupleSelect(
                2)));
            ho_Image.Dispose();
            ho_GrayImage.Dispose();
            ho_Region.Dispose();
            ho_ConnectedRegions.Dispose();
            ho_SelectedRegions.Dispose();
            ho_RegionTrans.Dispose();
            ho_RegionFillUp.Dispose();
            ho_RegionUnion.Dispose();
            ho_ImageReduced1.Dispose();
            ho_SortedRegions.Dispose();
            ho_EmptyObject.Dispose();
            ho_ObjectSelected.Dispose();
            ho_ImageReduced2.Dispose();
            ho_SymbolXLDs.Dispose();
        }

        public void InitHalcon()
        {
            // Default settings used in HDevelop
            HOperatorSet.SetSystem("width", 512);
            HOperatorSet.SetSystem("height", 512);
        }

        public void RunHalcon(HTuple Window)
        {
            hv_ExpDefaultWinHandle = Window;
            action();
        }
    }
}